package com.Algorithm;

import com.DAO.DAO;
import com.Entity.Employee;
import com.Entity.EmployeeLanguages;
import com.Entity.EmployeeProjects;
import com.Entity.EmployeeTests;
import java.util.Collection;
import java.util.List;

public class Criterion {
	
    public static int NUMBER_OF_CRITERIONS = 6;

    private static int PUNCTUALITY_WEIGHT = 2;
    private static int PLANNING_WEIGHT = 4;
    private static int DECISION_MAKING_WEIGHT = 5;
    private static int PEOPLE_MANAGEMENT_WEIGHT = 2;
    private static int COMMUNICATIONS_WEIGHT = 3;
    private static int CREATIVITY_WEIGHT = 5;
    private static int RESISTANCE_TO_STRESS_WEIGHT = 5;
    private static int NUMBER_OF_POINTS = 10;

    private Employee employee;
    private DAO dao;

    public Criterion(Employee employee)
    {
        this.employee = employee;
        this.dao = new DAO();
    }

    /**
     * Criterion 1 - experience in project management.
     * @return result of criterion 1
     */
    public double criterion_1() 
    {
        List<EmployeeProjects> managingProjects = dao.getManagingProjects(employee.getIdEmployee());
        
        double pNumberOfManagingProjects = employee.getOtherProjects() + dao.getManagingProjects(employee.getIdEmployee()).size();
        
        double pManagementTime  = 0.0;
        double end, start;
        for (EmployeeProjects ep : managingProjects )
        {
            start = ep.getStartDate().getTime();
            end = ep.getEndDate() != null ? ep.getEndDate().getTime() : System.currentTimeMillis();
            pManagementTime += (end - start) / (1000 * 60 * 60 * 24);
        }
        
        pManagementTime /= 365;
        pManagementTime += employee.getTimeOtherProjects();
        
        return pNumberOfManagingProjects * pManagementTime;
    }


    /**
     * Criterion 2 - knowledge.
     * @return result of criterion 2
     */
    public double criterion_2() 
    {
        int pPosition = Integer.parseInt(employee.getPosition());
        if (pPosition == 2) pPosition = 3;
        if (pPosition == 3) pPosition = 5;
        int pEducation = Integer.parseInt(employee.getEducation());
        
        Collection<EmployeeLanguages> employeeLanguages = employee.getEmployeeLanguagesCollection();
        int maxL = 3;
        double pForeignLanguages = 0.0;
        String levelL;
        for (EmployeeLanguages el : employeeLanguages)
        {
            if (maxL > 0)
            {
                levelL = el.getLevel();
                switch(levelL)
                {
                    case "A1" :
                        pForeignLanguages += 0.25;
                        break;
                    case "A2" :
                        pForeignLanguages += 0.5;
                        break;
                    case "B1" :
                        pForeignLanguages += 0.75;
                        break;
                    case "B2" :
                        pForeignLanguages += 1;
                        break;
                    case "C1" :
                        pForeignLanguages += 1.25;
                        break;
                    case "C2" :
                        pForeignLanguages += 1.5;
                        break;
                }
            }
            else 
            {
                break;
            }
            maxL--;
        }
         
        double pCertificates = employee.getCertifications();
                
        return pPosition + pEducation + pForeignLanguages + pCertificates;
    }


    /**
     * Criterion 3 - budget management skills.
     * @return result of criterion 3
     */
    public double criterion_3() 
    {
        
        EmployeeTests employeeTest = dao.getEmployeeTest(employee.getIdEmployee());
        int pPunctuality = employeeTest.getPunctuality();
        int pPlanning = employeeTest.getPlanning();
        int pDecisionMaking = employeeTest.getDecisionMaking();

        double numerator = pPunctuality * PUNCTUALITY_WEIGHT 
                                         + pPlanning * PLANNING_WEIGHT 
                                         + pDecisionMaking * DECISION_MAKING_WEIGHT;

        double denominator = NUMBER_OF_POINTS * (PUNCTUALITY_WEIGHT + PLANNING_WEIGHT + DECISION_MAKING_WEIGHT);

        return numerator / denominator;
    }


    /**
     * Criterion 4 - "soft" skills.
     * @return result of criterion 4
     */
    public double criterion_4() 
    {
        EmployeeTests employeeTest = dao.getEmployeeTest(employee.getIdEmployee());
        int pPeopleManagement = employeeTest.getManagementPeople();
        int pCommunication = employeeTest.getCommunications();
        int pCreativity = employeeTest.getCreativity();
        int pResistanceToStress = employeeTest.getResistanceStress();
        
        double numerator = pPeopleManagement * PEOPLE_MANAGEMENT_WEIGHT 
                                         + pCommunication * COMMUNICATIONS_WEIGHT 
                                         + pCreativity * CREATIVITY_WEIGHT
                                         + pResistanceToStress * RESISTANCE_TO_STRESS_WEIGHT;

        double denominator = NUMBER_OF_POINTS * (PEOPLE_MANAGEMENT_WEIGHT + COMMUNICATIONS_WEIGHT + CREATIVITY_WEIGHT + RESISTANCE_TO_STRESS_WEIGHT);

        return numerator / denominator;
    }


    /**
     * Criterion 5 - availability.
     * @return - result of criterion 5
     */
    public double criterion_5() 
    {
        double pWorkTime = employee.getEmployment();
        int pNumberOfProjects = dao.getCurrentProjects(employee.getIdEmployee()).size();
                
        return pNumberOfProjects > 0 ? pWorkTime / pNumberOfProjects : 0;
    }


    /**
     * Criterion 6 - work experience.
     * @return - result of criterion 6
     */
    public double criterion_6() 
    {
        double pWorkExperienceCompany = ((System.currentTimeMillis() - employee.getDateEmployment().getTime()) / (1000 * 60 * 60 * 24));
        pWorkExperienceCompany /= 365;
        double pWorkExperienceIT = employee.getWorkIt() + pWorkExperienceCompany;
        
        return pWorkExperienceCompany + pWorkExperienceIT;
    }
	

}
